import { defineComponent, onMounted, PropType, ref, VNode, watch } from 'vue';
import { onRouteChange, useNamespace } from '@ibiz-template/vue3-util';
import { MenuItem } from '@imengyu/vue3-context-menu';
import { TabsPaneContext } from 'element-plus';
import { IPanelRawItem } from '@ibiz/model-core';
import { NavTabsController, TabMsg } from '../../controller';
import './top-nav-tabs.scss';

export interface IActionItem {
  label: string;
  value: string;
  icon: JSX.Element;
}

export const TopNavTabs = defineComponent({
  name: 'IBizTopNavTabs',
  props: {
    modelData: {
      type: Object as PropType<IPanelRawItem>,
      required: true,
    },
    controller: {
      type: NavTabsController,
      required: true,
    },
  },
  setup(props) {
    const ns = useNamespace('top-nav-tabs');
    const c = props.controller;
    const { state } = props.controller;
    const visible = ref(false);
    // 下拉菜单项
    const actions: IActionItem[] = [
      {
        label: '刷新',
        value: 'refresh',
        icon: <ion-icon name='sync'></ion-icon>,
      },
      {
        label: '关闭其他',
        value: 'closeOther',
        icon: <ion-icon name='close'></ion-icon>,
      },
      {
        label: '关闭左侧',
        value: 'closeLeft',
        icon: <ion-icon name='arrow-back'></ion-icon>,
      },
      {
        label: '关闭右侧',
        value: 'closeRight',
        icon: <ion-icon name='arrow-forward'></ion-icon>,
      },
      {
        label: '关闭全部',
        value: 'closeAll',
        icon: <ion-icon name='close'></ion-icon>,
      },
    ];

    let ContextMenu: IData;

    onMounted(() => {
      const importMenu = () => import('@imengyu/vue3-context-menu');
      importMenu().then(value => {
        ContextMenu = value.default;
        if (ContextMenu.default && !ContextMenu.showContextMenu) {
          ContextMenu = ContextMenu.default;
        }
      });
    });

    if (c.routeDepth) {
      onRouteChange(args => {
        c.onRouteChange(args);
      }, c.routeDepth + 1);
    }

    watch(
      () => c.state.currentKey,
      (newVal, oldVal) => {
        if (newVal !== oldVal) {
          const findItem = c.findTabItem(newVal);
          // 如果tabItems里有说明是路由切换
          if (findItem) state.activeTab = newVal;
        }
      },
    );

    // 切换tab
    const changePage = (pane: TabsPaneContext): void => {
      if (state.currentKey !== pane.paneName) {
        c.onTabClick(pane.paneName as string);
      }
    };

    // 删除tab
    const onTabRemove = (key: string): void => {
      c.onTabRemove(key);
    };

    // 处理下拉点击
    const handleActionClick = (actionId: string): void => {
      visible.value = false;
      switch (actionId) {
        case 'refresh':
          c.refresh();
          break;
        case 'closeAll':
          c.removeAll();
          break;
        case 'closeOther':
          c.removeOther();
          break;
        case 'closeLeft':
          c.removeLeft();
          break;
        case 'closeRight':
          c.removeRight();
          break;
        default:
          break;
      }
    };

    /**
     * 计算上下文菜单项
     *
     * @param {IActionItem} _msg
     * @return {*}  {MenuItem[]}
     */
    const calcContextMenuItems = (_msg: TabMsg): MenuItem[] => {
      const menuItems: MenuItem[] = [];
      actions.forEach(action => {
        menuItems.push({
          label: action.label,
          icon: action.icon,
          customClass: ns.em('context-menu', 'item'),
          onClick: () => handleActionClick(action.value),
        });
      });
      return menuItems;
    };

    /**
     * 处理右键上下文菜单
     *
     * @param {MouseEvent} evt
     * @param {IActionItem} msg
     * @return {*}  {void}
     */
    const handleContextmenu = (evt: MouseEvent, msg: TabMsg): void => {
      // 阻止原生浏览器右键菜单打开
      evt.preventDefault();
      evt.stopPropagation();
      const menuItems: MenuItem[] = calcContextMenuItems(msg);
      if (!menuItems.length) return;
      ContextMenu.showContextMenu({
        x: evt.x,
        y: evt.y,
        minWidth: 110,
        items: menuItems,
        customClass: ns.e('context-menu'),
      });
    };

    return {
      c,
      ns,
      visible,
      actions,
      changePage,
      onTabRemove,
      handleActionClick,
      handleContextmenu,
    };
  },
  render() {
    const { state } = this.controller;
    return (
      <div class={[this.ns.b(), ...this.controller.containerClass]}>
        <div class={this.ns.e('left')}>
          <el-tabs
            type='card'
            v-model={state.activeTab}
            onTabClick={this.changePage}
            onTabRemove={this.onTabRemove}
          >
            {state.tabItems.map(msg => {
              let label = msg.caption;
              if (msg.dataInfo) label += ` - ${msg.dataInfo}`;
              return (
                <el-tab-pane
                  name={msg.key}
                  key={msg.key}
                  label={label}
                  closable={!(this.c.state.defaultActiveKey === msg.key)}
                >
                  {{
                    label: (): VNode => {
                      return (
                        <div
                          class={this.ns.e('item')}
                          title={label}
                          onContextmenu={evt =>
                            this.handleContextmenu(evt, msg)
                          }
                        >
                          <iBizIcon
                            class={this.ns.em('item', 'icon')}
                            icon={msg.sysImage}
                          />
                          <div class={this.ns.em('item', 'caption')}>
                            {label}
                          </div>
                        </div>
                      );
                    },
                  }}
                </el-tab-pane>
              );
            })}
          </el-tabs>
        </div>
        <div class={this.ns.e('right')}>
          <el-popover
            trigger='hover'
            placement='bottom-end'
            v-model:visible={this.visible}
            popper-class={this.ns.e('popover')}
          >
            {{
              reference: () => {
                return (
                  <span
                    class={this.ns.e('more')}
                    title={ibiz.i18n.t('app.more')}
                  >
                    <i
                      class={[
                        this.ns.em('more', 'icon'),
                        this.ns.em('more', 'left'),
                      ]}
                    ></i>
                    <i
                      class={[
                        this.ns.em('more', 'icon'),
                        this.ns.em('more', 'right'),
                      ]}
                    ></i>
                  </span>
                );
              },
              default: () => {
                return this.actions.map(action => {
                  return (
                    <div
                      class={this.ns.em('popover', 'item')}
                      onClick={() => this.handleActionClick(action.value)}
                    >
                      <div class={this.ns.em('popover', 'item-icon')}>
                        {action.icon}
                      </div>
                      <div class={this.ns.em('popover', 'item-caption')}>
                        {action.label}
                      </div>
                    </div>
                  );
                });
              },
            }}
          </el-popover>
        </div>
      </div>
    );
  },
});
